package examples.rrc;

import java.io.*;
import java.net.*;
import mac.filter.*;

public class RRCEventRecognizer extends Thread {
  public final static int DEFAULT_INPUT_PORT = 8040;
  public final static int DEFAULT_OUTPUT_PORT = 8041;
  public String checker;
  protected int port;
  protected ServerSocket listen_socket;

  public static void fail(Exception e, String msg) {
    System.err.println(msg + ":" + e);
    System.exit(1);
  }

  public RRCEventRecognizer(int port, String checker) {
    this.checker = checker;

    if (port == 0)
      port = DEFAULT_INPUT_PORT;
    this.port = port;
    try {
      listen_socket = new ServerSocket(port);
    } catch (IOException e) {
      fail(e, "Exception creating RRCEventRecognizer socket");
    }
    System.out.println("RRCEventRecognizer:listening on port " + port);
    this.start();
  }

  public void run() {
    try {
      while (true) {
        Socket client_socket = listen_socket.accept();
        Connection c = new Connection(client_socket, checker);
      }
    } catch (IOException e) {
      fail(e, "Exception while listening for connections");
    }
  }

  // Arg[0] : listening port
  // arg[1] : Checker host name:port#
  public static void main(String[] args) {
    String checker = null;
    int port = 0;
    if (args.length == 2) {
      try {
        port = (Integer.valueOf(args[0])).intValue();
        checker = args[1];
      } catch (NumberFormatException e) {
        port = 0;
      }
    }
    new RRCEventRecognizer(port, checker);
  }
}

class Connection extends Thread {
  protected Socket client;
  Socket checker;
  protected DataInputStream in;
  protected ObjectInputStream o_in;
  PrintWriter out;
  static final String CHECKER_HOST = "saul.cis.upenn.edu";
  static final int CHECKER_PORT = 8041;

  int train_length;
  int cross_x;
  int cross_length;
  float train_x;
  boolean IC;

  public Connection(Socket client_socket, String checkername) {
    client = client_socket;
    IC = false;
    String checkerHost = checkername.substring(0, checkername.lastIndexOf(":"));
    int checkerPort = (Integer.valueOf(checkername.substring(checkername
        .lastIndexOf(":") + 1, checkername.length()))).intValue();
    try {
      in = new DataInputStream(client.getInputStream());
      o_in = new ObjectInputStream(in);
      checker = new Socket(checkerHost, checkerPort);
      out = new PrintWriter(checker.getOutputStream());
      if (out != null) {
        System.err.println("Connection to RRCChecker established");
      }
    } catch (IOException e) {
      try {
        client.close();
      } catch (IOException e2) {
      }
      System.err.println("Exception while getting socket streams: " + e);
      return;
    }
    this.start();
  }

  public void run() {
    String line;
    StringBuffer revline;
    int len;
    SnapshotObj s_o;

    try {
      for (;;) {
        s_o = (SnapshotObj) o_in.readObject();
        System.out.println(s_o);
        detectEvent(s_o);
      }
    } catch (EOFException e) {
    } catch (IOException e) {
      System.err.println(e);
    } catch (ClassNotFoundException e) {
      System.err.println(e);
    } finally {
      try {
        client.close();
      } catch (IOException e2) {
      }
    }
  }

  void detectEvent(SnapshotObj s_o) {
    String var = s_o.getVarId();
    Object value = s_o.getVar();
    String PC = null;
    String event = null;

    // System.out.println(s_o.getVarId()+"|" + s_o.getVar()+"|");

    if (var.equals("PC")) {
      if (value.equals("start of Gate.gu")) {
        event = "endGD";
      } else if (s_o.getVar().equals("end of Gate.gd")) {
        event = "startGD";
      }
    } else if (var.equals("RRC.train_x")) {
      train_x = ((Float) value).floatValue();
      if (train_x + train_length > cross_x && train_x <= cross_x + cross_length
          && IC == false) {
        IC = true;
        event = "startIC";
      }
      if ((train_x + train_length <= cross_x || train_x > cross_x
          + cross_length)
          && IC == true) {
        IC = false;
        event = "endIC";
      }

    } else if (var.equals("RRC.train_length")) {
      train_length = ((Integer) value).intValue();
    } else if (var.equals("RRC.cross_x")) {
      cross_x = ((Integer) value).intValue();
    } else if (var.equals("RRC.cross_length")) {
      cross_length = ((Integer) value).intValue();
    }

    if (event != null) {
      System.out.println(event);
      out.println(event);
      out.flush();
      event = null;
    }

  }
}
